using B.S.DataBase.MyProject.Infrastructure.Implement;
using B.S.DataBase.MyProject.Infrastructure.Interface;
using B.S.DataBase.MyProject.Infrastructure;
using Microsoft.EntityFrameworkCore;
using System.Reflection;
using MedicalPCTerminal.Write.API.Filters;
using Yitter.IdGenerator;
using Microsoft.OpenApi.Models;
using MedicalPCTerminal.Write.API.Common;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Extensions.Options;
using ServiceManagement.Consul;
namespace MedicalPCTerminal.Write.API
{
    /// <summary>
    /// 程序入口类
    /// </summary>
    public class Program
    {
        /// <summary>
        /// 应用程序入口点
        /// </summary>
        /// <param name="args">命令行参数</param>
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.

            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            ////
            //builder.Services.AddDbContext<SDbContext>(x => x.UseMySql(builder.Configuration.GetConnectionString("Db"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("Db"))));
            //ע
            builder.Services.AddSwaggerGen(x =>
            {
                var path = AppDomain.CurrentDomain.BaseDirectory + "MedicalPCTerminal.Write.API.xml";
                x.IncludeXmlComments(path, true);
            });

            builder.Services.AddSignalR();

            // 添加CORS策略
            builder.Services.AddCors(options =>
            {
                options.AddPolicy("AllowAll", builder =>
                {
                    builder.AllowAnyOrigin()
                           .AllowAnyMethod()
                           .AllowAnyHeader();
                });
            });

            // ȡݿַ
            var connectionString = builder.Configuration.GetConnectionString("Db");
            //sqlsugar
            builder.Services.AddScoped<SqlSugarContext>();

            //ȫ쳣
            builder.Services.AddControllers(c => c.Filters.Add<MyExceptionFilter>());
            //ִ
            builder.Services.AddScoped(typeof(IBaseRepository<>), typeof(BaseRepository<>));

            //עн
            builder.Services.AddMediatR(x => x.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()));

            //עautomapper
            builder.Services.AddAutoMapper(typeof(AutoMapperFilePro));

            //ѩId
            YitIdHelper.SetIdGenerator(new IdGeneratorOptions(0));
            builder.Configuration.Register();
            //读取配置文件
            var jwtSettings = builder.Configuration.GetSection("JwtSettings").Get<JwtSettings>();
            //Ȩ֤ʹJWT
            builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(o =>
            {
                // ˽Կ
                //var secretByte = Encoding.UTF8.GetBytes("kdsfldsflkdslkflkdsflkdslfdslkflk");
                var secreByte = Encoding.UTF8.GetBytes(jwtSettings.secretByte);
                o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                {
                    // ֤
                    ValidateIssuer = true,
                    // Ϣ
                    ValidIssuer = jwtSettings.Issuer,

                    // ֤
                    ValidateAudience = true,
                    // 
                    ValidAudience = jwtSettings.Audience,

                    // ֤Ƿ
                    ValidateLifetime = true,

                    // ֤˽Կ
                    IssuerSigningKey = new SymmetricSecurityKey(secreByte)
                };
                
                // 添加对 SignalR 的支持
                o.Events = new JwtBearerEvents
                {
                    OnMessageReceived = context =>
                    {
                        var accessToken = context.Request.Query["access_token"];
                        var path = context.HttpContext.Request.Path;
                        
                        if (!string.IsNullOrEmpty(accessToken) && 
                            path.StartsWithSegments("/api/chathub"))
                        {
                            context.Token = accessToken;
                        }
                        return Task.CompletedTask;
                    }
                };
            });
            // Swagger
            builder.Services.AddSwaggerGen(o =>
            {
                // ȡǰ򼯵
                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                // ȡXMLļ·
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                // XMLעļ
                o.IncludeXmlComments(xmlPath);

                // ֧עʾ
                o.CustomSchemaIds(type => type.FullName);
                // ʾ ȨϢ
                o.AddSecurityDefinition("Bearer", new Microsoft.OpenApi.Models.OpenApiSecurityScheme()
                {
                    Description = "JWTȨTokenBearer Tokenֵ",
                    Name = "Authorization",
                    In = Microsoft.OpenApi.Models.ParameterLocation.Header,
                    Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey,
                    BearerFormat = "JWT",
                    Scheme = "Bearer"
                });
                o.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id = "Bearer"
                            }
                        },
                        new string[]
                        {

                        }
                    }
                });
            });

            var app = builder.Build();
            
            // 使用CORS
            app.UseCors("AllowAll");
            
            // 配置中间件顺序
            app.UseRouting();

            // 启用静态文件服务
            app.UseDefaultFiles();
            app.UseStaticFiles();
            
            // 配置 SignalR
            app.MapHub<ChatHub>("/api/chathub");
            
            // Configure the HTTP request pipeline.
            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "Medical PC Terminal API V1");
            });

            // 认证和授权中间件
            app.UseAuthentication();
            app.UseAuthorization();

            app.MapControllers();

            // 添加聊天测试页面路由
            app.MapGet("/chat", async context =>
            {
                context.Response.ContentType = "text/html";
                await context.Response.SendFileAsync(Path.Combine(app.Environment.ContentRootPath, "wwwroot", "chat-test.html"));
            });

            app.Run();
        }
    }
}
